{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "dd4d3b44-8b58-47d2-852a-59ac8a98390f",
   "metadata": {},
   "source": [
    "### 导入依赖库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c3340fc5-6407-47c1-9efb-d1fc2fbc1890",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.chat_models import ChatZhipuAI\n",
    "from langchain_core.messages import AIMessage, HumanMessage, SystemMessage\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from langchain_core.prompts import FewShotChatMessagePromptTemplate\n",
    "from langchain_core.messages import AIMessage, HumanMessage, SystemMessage\n",
    "from langchain_core.output_parsers import JsonOutputParser\n",
    "from langchain_core.pydantic_v1 import BaseModel, Field\n",
    "from langchain.output_parsers import CommaSeparatedListOutputParser"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85d760be-1178-4c82-bda0-9a19a8e9789d",
   "metadata": {},
   "source": [
    "### 配置API密钥"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ed3d9808-e534-4d1d-9628-29de959fcea6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ[\"ZHIPUAI_API_KEY\"] = \"你的api key\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f2c0c2b-7cc8-46d3-8be6-167dc12952d4",
   "metadata": {},
   "source": [
    "### 初始化GLM-4-Flash模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "6b61dacb-b723-42d4-8eae-612bf6fdbef9",
   "metadata": {},
   "outputs": [],
   "source": [
    "chat = ChatZhipuAI(\n",
    "    model=\"glm-4-flash\",\n",
    "    temperature=0.5,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87b0bd2e-03dc-4d16-a5c6-91ff27d13c75",
   "metadata": {},
   "source": [
    "### 单轮对话模板"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "44973fca-ad37-4946-a32f-4a4a99dc4db9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "哈，老哥，来聊聊这个LangChain啊。这玩意儿在AI界可是挺火的，咱们就当个贴吧老哥，来聊聊这东西。\n",
      "\n",
      "首先，LangChain这名字听起来就挺高端大气，像是哪个科研机构或者大公司搞出来的。它本质上是一个构建大型语言模型的工具链，听起来就像是个AI界的瑞士军刀，能解决不少问题。\n",
      "\n",
      "优点嘛，老哥，首先它集成度挺高，把各种AI模型、数据处理、模型训练的功能都整合在一起，对于做语言模型开发的人来说，这简直就是福音，不用东拼西凑，一套工具链就能搞定很多事儿。\n",
      "\n",
      "其次，LangChain的扩展性也不错，可以方便地接入各种外部库和API，对于开发者来说，灵活性挺高，可以根据自己的需求来定制。\n",
      "\n",
      "但是，老哥，凡事都有两面性，LangChain也有它的槽点。\n",
      "\n",
      "首先，这玩意儿可能对新手不太友好。它那么强大，功能又多，不熟悉的人可能会觉得操作起来有点复杂，有点像是个大杂烩，需要一定的学习成本。\n",
      "\n",
      "再者，这么强大的工具链，资源消耗肯定不低。对于一些资源有限的小团队或者个人开发者来说，可能得掂量掂量自己的服务器配置能不能撑得住。\n",
      "\n",
      "最后，老哥，我得说说这东西的生态。虽然LangChain本身挺强大，但是周边的生态可能还不够完善，一些配套的工具和资源可能还需要时间去积累。\n",
      "\n",
      "总的来说，LangChain是个挺不错的工具，对于有需求的人来说，是个不错的选择。但是，老哥，用这东西之前，也得考虑清楚自己的需求、团队实力和资源情况，别到时候搞了个大新闻，自己却忙得焦头烂额。\n"
     ]
    }
   ],
   "source": [
    "# 创建角色定制模板\n",
    "template = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"你是一位{style}风格的评论家\"),\n",
    "    (\"human\", \"请评价以下事物：{things}\")]\n",
    ")\n",
    "\n",
    "# 动态填充参数\n",
    "messages = template.format_messages(\n",
    "    style=\"贴吧老哥\", \n",
    "    things=\"langchain\"\n",
    ")\n",
    "\n",
    "# 调用模型\n",
    "response = chat.invoke(messages)\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a26e191-7857-40c0-be36-00d2534ece9b",
   "metadata": {},
   "source": [
    "### 多轮对话模板（手动管理历史）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e7797b18-d94a-4985-9d4f-15e5db08d39b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当然可以。ChatGPT 和 DeepSeek 都是人工智能领域的先进技术，它们各自有不同的优势。以下是对两者优势的详细说明：\n",
      "\n",
      "### ChatGPT 的优势：\n",
      "\n",
      "1. **强大的语言处理能力**：ChatGPT 是由 OpenAI 开发的，基于 GPT-3.5 模型，具有非常强大的自然语言处理能力，能够进行流畅的对话，理解复杂的语言结构和语境。\n",
      "\n",
      "2. **广泛的领域知识**：ChatGPT 接受了大量的文本数据训练，因此它对各种领域的知识都有所了解，能够回答各种问题。\n",
      "\n",
      "3. **跨平台应用**：ChatGPT 可以在多个平台上运行，包括网页、移动应用等，用户可以在不同的设备上与它互动。\n",
      "\n",
      "4. **社区支持**：由于 ChatGPT 是由 OpenAI 开发的，背后有一个强大的社区和团队支持，不断进行更新和改进。\n",
      "\n",
      "5. **商业应用潜力**：ChatGPT 在客户服务、内容创作、教育等多个商业领域都有广泛的应用潜力。\n",
      "\n",
      "### DeepSeek 的优势：\n",
      "\n",
      "1. **深度学习技术**：DeepSeek 利用深度学习技术，在图像识别、语音识别等领域表现出色，特别是在复杂场景下的图像理解能力。\n",
      "\n",
      "2. **国内研发**：DeepSeek 是中国自主研发的技术，体现了中国在人工智能领域的创新能力和技术实力。\n",
      "\n",
      "3. **特定领域的深度应用**：DeepSeek 在特定领域（如医疗、安防等）有深入的研究和应用，能够提供针对性强、专业化的解决方案。\n",
      "\n",
      "4. **高效的数据处理能力**：DeepSeek 在处理大量数据时表现出高效，能够快速从数据中提取有价值的信息。\n",
      "\n",
      "5. **安全性**：DeepSeek 在设计和应用过程中注重数据安全和隐私保护，符合国内外的数据保护法规。\n",
      "\n",
      "总的来说，ChatGPT 和 DeepSeek 在各自领域都有显著的优势。ChatGPT 强调的是通用性和跨领域的对话能力，而 DeepSeek 则在特定技术领域和安全性方面表现出色。两者都是人工智能技术发展的重要成果，代表了不同方向上的创新和突破。\n"
     ]
    }
   ],
   "source": [
    "# 包含历史上下文的模板\n",
    "history_template = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"你正在与用户讨论{theme}。以下是之前的对话历史：\\n{history}\"),\n",
    "    (\"human\", \"{input}\")\n",
    "])\n",
    "\n",
    "# 填充历史与输入\n",
    "messages = history_template.format_messages(\n",
    "    theme=\"目前AI发展的趋势\",\n",
    "    history=[\n",
    "        HumanMessage(content=\"国外的chatgpt怎么样\"),\n",
    "        AIMessage(content=\"还行，也就那样，我认为国内deepseek无敌\")\n",
    "    ],\n",
    "    input=\"详细说说他们的优势\"\n",
    ")\n",
    "\n",
    "# 调用模型\n",
    "response = chat.invoke(messages)\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84f58eae-71a6-494d-a516-63df973d6af5",
   "metadata": {},
   "source": [
    "### Few-shot 提示与示例选择器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "541a121b-8bfd-4f5e-bab4-abfb1159f27b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "300\n"
     ]
    }
   ],
   "source": [
    "# 定义示例集\n",
    "examples = [\n",
    "    {\"input\": \"5*6\", \"output\": \"30\"},\n",
    "    {\"input\": \"4*6\", \"output\": \"24\"}\n",
    "]\n",
    "\n",
    "# 创建示例模板\n",
    "example_template = ChatPromptTemplate.from_messages([\n",
    "    (\"human\", \"{input}\"),\n",
    "    (\"ai\", \"{output}\")\n",
    "])\n",
    "\n",
    "# 组合成Few-shot提示\n",
    "few_shot_prompt = FewShotChatMessagePromptTemplate(\n",
    "    example_prompt=example_template,\n",
    "    examples=examples\n",
    ")\n",
    "\n",
    "# 最终提示结构\n",
    "final_prompt = ChatPromptTemplate.from_messages([\n",
    "    # ('system', '根据模板生成内容'),\n",
    "    few_shot_prompt,\n",
    "    (\"human\", \"{input}\")\n",
    "])\n",
    "\n",
    "# 使用示例\n",
    "response = chat.invoke(final_prompt.format_messages(input=\"25*12\"))\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "760fb042-d45f-48d5-a9a3-9170228ccf0e",
   "metadata": {},
   "source": [
    "### 结构化输出解析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "89467a56-41f2-4370-bdcc-8ed9b3910c50",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Python', 'JavaScript', 'Java']\n"
     ]
    }
   ],
   "source": [
    "# 列表\n",
    "\n",
    "\n",
    "parser = CommaSeparatedListOutputParser()\n",
    "format_instructions = parser.get_format_instructions()\n",
    "\n",
    "# 在提示中注入格式说明\n",
    "template = \"列出3种{category}:\\n{format_instructions}\"\n",
    "prompt = ChatPromptTemplate.from_template(template)\n",
    "chain = prompt | chat | parser\n",
    "\n",
    "result = chain.invoke({\n",
    "    \"category\": \"编程语言\",\n",
    "    \"format_instructions\": format_instructions\n",
    "})\n",
    "print(result) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "35549064-3bb0-4198-954c-f2ad261bd015",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': '辣味牛肉丝', 'steps': ['将牛肉切成细丝，用料酒、生抽、淀粉和少许盐腌制10分钟。', '将干辣椒剪成小段，蒜切成末，姜切成片。', '锅中放油，油热后放入干辣椒、蒜末和姜片爆香。', '加入腌制好的牛肉丝快速翻炒至变色。', '加入适量的生抽、老抽调色，再加入适量的料酒。', '加入青椒丝和红椒丝继续翻炒。', '最后加入适量的盐、糖、鸡精调味，炒匀后即可出锅。']}\n"
     ]
    }
   ],
   "source": [
    "# json\n",
    "\n",
    "\n",
    "\n",
    "# 定义数据结构\n",
    "class Recipe(BaseModel):\n",
    "    name: str = Field(description=\"菜谱名称\")\n",
    "    steps: list[str] = Field(description=\"制作步骤\")\n",
    "\n",
    "# 创建解析器\n",
    "parser = JsonOutputParser(pydantic_object=Recipe)\n",
    "\n",
    "# 构建提示链\n",
    "prompt = ChatPromptTemplate.from_template(\n",
    "    \"生成{cuisine}菜谱，要求：{requirements}\\n{format_instructions}\"\n",
    ")\n",
    "chain = prompt | chat | parser\n",
    "\n",
    "result = chain.invoke({\n",
    "    \"cuisine\": \"川菜\",\n",
    "    \"requirements\": \"辣度适中，包含牛肉\",\n",
    "    \"format_instructions\": parser.get_format_instructions()\n",
    "})\n",
    "\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63fe2029-3989-422f-a680-7447255aea86",
   "metadata": {},
   "source": [
    "###  工具调用（需模型支持）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "739a1fd1-4adb-430b-bef0-b982ab17643f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 工具创建\n",
    "from langchain_core.tools import tool\n",
    "\n",
    "@tool\n",
    "def get_weather(city: str) -> str:\n",
    "    \"\"\"获取指定城市的天气信息\"\"\"\n",
    "    # 此处应调用真实API，示例返回静态数据\n",
    "    return f\"{city}：晴，25℃\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "3db5178c-a902-4bf3-8699-8823340a4115",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='' additional_kwargs={'tool_calls': [{'function': {'arguments': '{\"city\": \"北京\"}', 'name': 'get_weather'}, 'id': 'call_-8828734222680606890', 'index': 0, 'type': 'function'}]} response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 147, 'total_tokens': 157}, 'model_name': 'glm-4-flash', 'finish_reason': 'tool_calls'} id='run-e2b810e0-c3bc-4ecf-8461-fcf705f04d53-0' tool_calls=[{'name': 'get_weather', 'args': {'city': '北京'}, 'id': 'call_-8828734222680606890', 'type': 'tool_call'}]\n"
     ]
    }
   ],
   "source": [
    "#  工具装订\n",
    "\n",
    "prompt = ChatPromptTemplate.from_template(\"查询{city}天气\")\n",
    "chain = prompt | chat.bind_tools([get_weather])\n",
    "\n",
    "# 工具调用\n",
    "response = chain.invoke({\"city\": \"北京\"})\n",
    "print(response)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d43da93-2e36-4437-b517-2edfeea0de15",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
